var window, platform, log, win, isDebug = false, isFull, isPhone = false, enableSSL=false;
if (window.cordova == undefined) {
    //判斷目前是使用NW.js 還是electron
    try{
        try{
            // 20240321 modify by Alan for#159805 : electron升級後，兼容新舊版本
            const remote = window.nodeRequire('electron').remote || window.nodeRequire('@electron/remote');
            window = win = remote.getCurrentWindow();
            var appVersion = remote.app.getVersion();
            if(appVersion != '6.0.1'){
                //win.setFullScreen(false);
                win.setMinimumSize(920, 120);
                win.setSize(920, 120);
                win.center();
                win.setResizable(false);
                win.setMaximizable(false);
                isFull = true;
            }
            platform = 'electron';
        } catch(e){
            window = win = nodeRequire('nw.gui').Window.get();
            isFull = true;
            platform = 'nw';
        }
    }catch(e){
        //platform = 'web';
    }
    //網頁時的啟動
    angular.element().ready(startup);
} else {
    //裝置上運行時的啟動
    document.addEventListener('deviceready', function(){
        try{
            //設定全螢幕
            window.AndroidFullScreen.immersiveMode(function(){
                //console.log('It worked!');
            }, function(error){
                console.error(error);
            });


            //20190410 modify by Dustdusk for M#: 判斷是否為iPhone or iPod
            if(navigator.userAgent.match(/(iPhone|iPod)/)){
                if(screen.lockOrientation!=undefined)
                    screen.lockOrientation('portrait');
                else if(screen.orientation.lock)
                    screen.orientation.lock('portrait');

                isPhone = true;
            } else if(navigator.userAgent.match(/(iPad)/)){
                if(screen.lockOrientation!=undefined)
                    screen.lockOrientation('landscape');
                else if(screen.orientation.lock)
                    screen.orientation.lock('landscape');
            } else {
                //不為i系列產品，需要根據螢幕大小判斷
                var height = window.screen.availHeight;
                var width = window.screen.availWidth;
                // 20221028 modify by Alan for M#115099:  修正手機尺寸判斷
                if((height <= 932 && width <= 430) || (height <= 430 && width <= 932)){
                    isPhone = true;
                }
            }

            //Avoid mobile devices click event 300ms delay
            window.FastClick.attach(document.body);

            //關閉狀態列
            window.StatusBar.hide();
            navigator.splashscreen.hide();
        } catch(e){
            console.error(e);
        }
        startup();
    }, false);
}

function startup(){
    init();
    if(platform != 'web'){
        //只要不是網頁版都有自動更新功能
        var domElement = document.querySelector('body');
        angular.bootstrap(domElement, ['update']);
    } else {
        document.location.href = 'index.html';
    }
}

function parseParamsToConfig(config){
    if(platform == 'electron' || platform == 'nw'){
        try{
            var outside_params = [];
            // 20240321 modify by Alan for#159805 : electron升級後，兼容新舊版本
            const remote = window.nodeRequire('electron').remote || window.nodeRequire('@electron/remote');
            if(platform == 'electron'){
                outside_params = remote.process.argv;
            } else if(platform == 'nw'){
                outside_params = nodeRequire('nw.gui').App.argv;
            }
            //20200103 modify by Dustdusk for M#:
            if(outside_params && outside_params.length == 2){
                if(outside_params[1].indexOf('smes:') == 0){
                    outside_params = outside_params[1].replace('smes:','').split('&');
                }
            }

            for(var index in outside_params){
                var param = outside_params[index];
                if(param.indexOf('-params?') == 0){
                    var paramArray = param.replace('-params?','').split(';');
                    for(var index_y in paramArray){
                        var keyValue = paramArray[index_y].split('=');
                        if(keyValue[0] == 'ip'){
                            config.server.ip = keyValue[1];
                        }
                        if(keyValue[0] == 'port'){
                            config.server.port = keyValue[1];
                        }
                        if(keyValue[0] == 'name'){
                            config.server.name = keyValue[1];
                        }
                        //20190306 modify by Dustdusk for M#: 增加傳入環境
                        if(keyValue[0] == 'env'){
                            config.setting.environment = keyValue[1];
                        }
                        if(keyValue[0] == 'ssl'){
                            enableSSL = keyValue[1];
                        }
                    }
                } else if(param.indexOf('-loginParams?') == 0){
                    config.login = {};
                    var paramArray = param.replace('-loginParams?','').split(';');
                    for(var index_y in paramArray){
                        var keyValue = paramArray[index_y].split('=');
                        if(keyValue[0] == 'id'){
                            config.login.account = keyValue[1].toUpperCase();
                        }
                        if(keyValue[0] == 'password'){
                            config.login.password = keyValue[1];
                        }
                        if(keyValue[0] == 'session'){
                            config.login.session = keyValue[1];
                        }
                    }
                } else if(param.indexOf('-debug') == 0){
                    if(platform == 'electron'){
                        isDebug = true;
                        remote.getCurrentWebContents().openDevTools();
                    } else if(platform == 'nw'){
                        isDebug = true;
                        win.showDevTools();
                    }
                } else if(param.indexOf('-phone') == 0){
                    isPhone = true;
                } else if(param.indexOf('-noneFullScreen') == 0){
                    config.setting.fullScreen = 'N';
                // 20240426 add by wenwei for M#162555: 雅典娜单点登陆
                } else if (param.indexOf('Athena') != -1) {
                    localStorage.setItem('AthenaLoginParameter', JSON.stringify(outside_params))
                }
            }
        }catch(e){
            console.error(e);
        }
    }
    config.setting.ssl = enableSSL;
    localStorage.setItem(config.appName + '_server', JSON.stringify(config.server));
    localStorage.setItem(config.appName + '_setting', JSON.stringify(config.setting));
    //20170731 modify by Dustdusk
    if(config.login){
        localStorage.setItem(config.appName + '_login', JSON.stringify(config.login));
    } else {
        localStorage.removeItem(config.appName + '_login');
    }
    return config;
}

//20211103 modify by Dustdusk for M#: 修正預設值
function init(){
    var app = angular.module('update', ['pascalprecht.translate','ngMaterialLite','angularCSS', 'sMESUpdate']), _config = {appName:'SMES', setting:{}};
    // 20221117 modify by Alan for M#118591:  修正startup.html的圖片失效問題
    app.config(['$httpProvider', '$provide', '$translateProvider', '$compileProvider',
        function($httpProvider, $provide, $translateProvider, $compileProvider) {
            let _localSetting = localStorage.getItem(_config.appName + '_setting');
            if(!_localSetting) {
                _localSetting = {"lang":(navigator.language||'zh-CN').replace('-', '_')};
            } else {
                _localSetting = JSON.parse(_localSetting);
            }
            $translateProvider.useStaticFilesLoader({ prefix: 'module/system/program/update/localization-', suffix: '.json' });
            $translateProvider.preferredLanguage(_localSetting.lang);
            _config.setting = _localSetting;
            $compileProvider.imgSrcSanitizationWhitelist(/^\s*((https?|ftp|file|blob|chrome-extension|appfile):|data:image\/)/);
            $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|chrome-extension|appfile):/);
        }
    ]);
    app.value('config', {});
    app.controller('update_controller', ['$scope', '$timeout', '$http', '$mdDialog', 'config', '$translate', '$filter', 'CommonService', 'HttpService','UpdateService',
    function($scope, $timeout, $http, $mdDialog, config, $translate, $filter, $CommonService, $HttpService, $UpdateService) {
        var updateInfo = {
                backgroundurl:'',
                need_update:false,
                default_modules:[]
            },
            download_root_path = '';

        $scope.mode = '';
		$scope.hostname = '';
        $scope.isFull = isFull;

        $scope.init = function(){
            //log.innerHTML = '...';
            log = document.getElementById('update_log');
            log.innerHTML = '...';
            $CommonService.changeMode = changeMode;
            $CommonService.platform = platform;
            $CommonService.reDirect = reDirect;
            $CommonService.writeLog = function(msg){
                log.innerHTML = msg;
            };
            downloadConfig();
        };

        $scope.close = function(){
            window.close();
        };

        $scope.reCheckUpdate = function(){
            config.setting.environment = $scope.environment;
            var temp = config.server.ip.split('.');
			//20201207 modify by Dustdusk for M#: 增加輸入host name
            if(temp.length == 4 && !isNaN(temp[0])){
                config.server.ip = combineIP($scope.serverIp);
            } else {
                config.server.ip = $scope.hostname;
            }
            config.server.port = (+$scope.port);
            config.server.name = $CommonService.server_name[ $scope.update_version][config.setting.environment];

            //20190214 modify by Dustdusk for M#: 改為取得伺服器名稱之後再儲存
            localStorage.setItem(config.appName + '_setting', JSON.stringify(config.setting));
            localStorage.setItem(config.appName + '_server', JSON.stringify(config.server));
            changeMode('');
            checkUpdate();
        };

        $scope.ChangeViewMode = function(mode){
            $scope.view_mode = mode;
            isPhone = $scope.view_mode == 'phone';
        }

        function downloadConfig(){
            // 20220929 modify by Alan for#118600 : 改用get取得config.json
            $http.get('config/config.json').then(function(res){

                //關閉全螢幕
                if(platform == 'electron')
                    win.setFullScreen(false);
                else if(platform == 'nw')
                    win.leaveFullscreen();

                angular.merge(config, res.data, _config);
                if(config.langList.indexOf(config.setting.lang) == -1){
                    config.setting.lang = 'zh_CN';
                }
                $scope.logoURL = `PN_home_${config.setting.lang}.png`;
                $translate.use(config.setting.lang);

                config.setting.ssl = enableSSL;
                //是否全螢幕
                if(!config.setting.fullScreen){
                    // 20231206 modify by Alan for#152125 : 首次啟動預設非全螢幕
                    config.setting.fullScreen = 'N';
                }

                //2. 從localStrorage 載入模組資訊、版本資訊
                config.file_appVersion = config.appVersion;
                var version_info = localStorage.getItem(config.appName + '_version');
                try{
                    version_info = JSON.parse(version_info);
                    if(version_info.appVersion!=null && version_info.appVersion!=''){
                        config.appVersion = version_info.appVersion;
                        // 20230222 modify by Alan for#128683 : iphone強制設為手機模式
                        if (navigator.userAgent.match(/(iPhone|iPod)/)) {
                            isPhone = true;
                        } else {
                            isPhone = version_info.isPhone === "Y";
                        }
                    }
                    updateInfo.default_modules =  version_info.module;
                }catch(e){
                    //舊版的version
                    if(version_info !== null)
                        config.appVersion = version_info;
                    for(var index in config.module){
                        updateInfo.default_modules.push({
                            name: config.module[index],
                            version:config.appVersion
                        });
                    }
                }
                $scope.versionList = ['209', '2010', '210'];
                //20190214 modify by Dustdusk for M#: 修正舊版本不會自動切換的問題
                var temp_version = config.appVersion.match(/(.\..\.[^\.]+)/)[0].replace(/\./g, '');
                if(temp_version == '2010'){
                    $scope.update_version = temp_version;
                } else if(temp_version <= '209'){
                    $scope.update_version = '209';
                } else {
                    $scope.update_version = '210';
                }
                //3. 從localStrorage 載入Server設定
                config.server = angular.merge({}, config.serverList[config.setting.environment]);//取出預設的Server資訊
                var LocalServerConfig = JSON.parse(localStorage.getItem(config.appName + '_server')||'{}');
                if(LocalServerConfig.ip != undefined){
                    config.server.ip = LocalServerConfig.ip;
                    config.server.port = LocalServerConfig.port;
                    config.server.timeout = LocalServerConfig.timeout;
                    //config.server.name = $CommonService.server_name[$scope.update_version][config.setting.environment];
                }
                //4. 從外部參數取得相關設定，覆蓋掉原本電腦內設定的內容
                parseParamsToConfig(config);
                $scope.config = config;
                config.server.name = $CommonService.server_name[$scope.update_version][config.setting.environment];
                $scope.environment = config.setting.environment;
                $scope.port = (+config.server.port);
                var temp = config.server.ip.split('.');
				//20201207 modify by Dustdusk for M#: 增加輸入host name
                if(temp.length == 4 && !isNaN(temp[0])){
                    $scope.serverIp = [(+temp[0]), (+temp[1]), (+temp[2]), (+temp[3])];
					$scope.hostname = '';
                } else {
                    $scope.serverIp = [0, 0, 0, 0];
					$scope.hostname = config.server.ip;
                }
                if(isPhone){
                    $scope.view_mode = 'phone';
                } else {
                    $scope.view_mode = 'pad';
                }

                angular.element(document.querySelector('#update_controller')).css('display','block');
                if(window.nodeRequire){
                    $scope.isElectron = true;
                    checkUpdate();
                } else if (window.cordova){
                    try{
                        navigator.splashscreen.hide();
                    } catch(e){
                        console.error(e);
                    }
                    $timeout(function(){
                        checkUpdate();
                    });
                } else {
                    changeMode('setting');
                }
            });
        }

        function checkUpdate(){
            if(config.server.ip != '0.0.0.0'){
                if(config.setting.ssl){
                    $CommonService.download_root_path = download_root_path = 'https://'+config.server.ip+':'+config.server.port;
                } else {
                    $CommonService.download_root_path = download_root_path = 'http://'+config.server.ip+':'+config.server.port;
                }

                //20181005 modify by Dustdusk for M#49171: 剛開啟程式時語系錯亂
                //20211103 modify by Dustdusk for M#: 修正東南亞語系問題
                let _chkMSG = $filter('translate')('update.msg.checking_update');
                if(_chkMSG =='update.msg.checking_update' ){
                    if($translate.use() == 'zh_TW'){
                        log.innerHTML = '檢查更新中...';
                    } else if($translate.use() == 'zh_CN'){
                        log.innerHTML = '检查更新中...';
                    } else {
                        $translate.use(config.setting.lang);
                        log.innerHTML = '检查更新中...';
                    }
                } else {
                    log.innerHTML = $filter('translate')('update.msg.checking_update');//檢查更新中...
                }

                $HttpService.send({
                    version : $scope.update_version,
                    env: config.setting.environment,
                    content:{is_mobile:isPhone},
                    success : function(data){
    
                        //更新多語系
                        if (data.language_details && data.language_details.length > 0) {
                            localStorage.setItem(config.appName + '_langList', JSON.stringify(data.language_details));
                        }
                        else {
                            localStorage.removeItem(config.appName + '_langList');
                        }

                        //updateInfo.module_details = angular.merge([], updateInfo.default_modules);
                        updateInfo.module_details = [];
                        updateInfo.target_version = $scope.update_version;//紀錄是要更新成哪一個版本
                        updateInfo.version = data.version;
                        updateInfo.url = download_root_path+'/'+data.url;
                        updateInfo.backgroundurl  = data.backgroundurl;
						//20201207 modify by Dustdusk for M#: 增加回傳語言清單
						updateInfo.lang_details = data.lang_details;
                        updateInfo.langversion = data.langversion;
                        updateInfo.langurl = data.langurl;
                        //20181004 modify by dustdusk for M#: 增加模組版本檢查
                        if(updateInfo.version != config.appVersion && updateInfo.version != '0.0.0.0'){
                            updateInfo.need_update = true;
                        }
						//檢查更新檔案是否存在
                        $UpdateService.checkUpdateExist(function(isExist){
                            if(!isExist)
                                updateInfo.need_update = true;

                            if(data.module_details && data.module_details.length>0){
                                data.module_details.forEach(function(update_module){
                                    var is_exist = false;
                                    for(var index in updateInfo.default_modules){
                                        var module = updateInfo.default_modules[index];
                                        if(module.name == update_module.name){
                                            //表示目前Client已有此程式
                                            is_exist = true;
                                            var temp_module = {
                                                name : update_module.name,
                                                version : update_module.version
                                            };
                                            if(updateInfo.need_update){
                                                //20200806 modify by Dustdusk for M#: 當update 程式有調整的時候，所有模組都瘀要重新下載
                                                temp_module.url = download_root_path +'/'+ update_module.url;
                                            } else if(module.version != update_module.version){
                                                //版本不同就壓url進去等待更新
                                                temp_module.url = download_root_path +'/'+ update_module.url;
                                            } else if(!$UpdateService.checkModuleExist(module.name)){
                                                //模組資料夾不在，還是需要重新下載
                                                temp_module.url = download_root_path +'/'+ update_module.url;
                                            }
                                            updateInfo.module_details.push(temp_module);
                                            break;
                                        }
                                    }
                                    if(!is_exist){
                                        //不存在原本的模組列表，那就加進去
                                        updateInfo.module_details.push({
                                            name : update_module.name,
                                            version : update_module.version,
                                            url : download_root_path +'/'+ update_module.url
                                        });
                                    }
                                });
                            }
                            $UpdateService.downloadUpdate(updateInfo);
                        });
                    }
                });
            } else {
                //一開始IP還未設定的時候
                changeMode('setting');
            }
        }

        function changeMode(mode){
            $timeout(function(){
                $scope.mode = mode;
                if(mode == 'setting'){
                    if(platform == 'electron'){
                        win.setSize(920, 360);
                        win.center();
                    } else if(platform == 'nw'){
                        win.resizeTo(920, 360);
                    }
                } else{
                    if(platform == 'electron'){
                        win.setSize(920, 120);
                        win.center();
                    } else if(platform == 'nw'){
                        win.resizeTo(920, 120);
                    }
                }
            });
        }

        function combineIP(array){
            var totalip;
            array.forEach(function(ipstring){
                if(totalip == undefined)
                    totalip = ipstring;
                else
                    totalip += '.' +ipstring;
            });
            return totalip;
        }

        function reDirect(url, msg){
            log.innerHTML = msg||$filter('translate')('update.msg.update_complete');//程式更新完成...
            //底層為Cordova 的狀態下，一旦更新完成就把新的版本號寫入localStorage
            var version_info = {
                appVersion: updateInfo.version,
                module:[],
                isPhone : isPhone?'Y':'N'
            };
            updateInfo.module_details.forEach(function(module_detail){
                version_info.module.push({
                    name:module_detail.name,
                    version:module_detail.version
                });
            });
            //20190307 modify by Dustdusk for M#: 修正平板降版後出問題
            if($scope.update_version != '210'){
                //將版本及模組資訊回寫至localstorage內
                localStorage.setItem(config.appName + '_version', updateInfo.version);
            } else {
                //將版本及模組資訊回寫至localstorage內
                localStorage.setItem(config.appName + '_version', JSON.stringify(version_info));
            }


            //20180507 modify by Dustdusk for M#45850: 一旦版本低於2.0.8 就將account及password 的設定清除
            try{
                var version = updateInfo.version.split('.');
                version = (+(version[0]+version[1]+version[2]));
                if(version < 208){
                    config.setting.account = '';
                    config.setting.password = '';
                    localStorage.setItem(config.appName + '_setting', JSON.stringify(config.setting));
                }
            }catch(e){
                console.error(e);
            }
            if(platform == 'electron'){
                createWindow(url);
            } else if(platform == 'nw'){
                createWindowNW(url);
            } else {
                //20191107 modify by Dustdusk for M#:
                try{
                    if(isPhone){
                        if(screen.lockOrientation!=undefined)
                            screen.lockOrientation('portrait');
                        else if(screen.orientation.lock)
                            screen.orientation.lock('portrait');
                    } else {
                        if(screen.lockOrientation!=undefined)
                            screen.lockOrientation('landscape');
                        else if(screen.orientation.lock)
                            screen.orientation.lock('landscape');
                    }
                }catch(e){}
                if(window.CacheClear){
                    window.CacheClear(function(){
                        window.location.href = url;
                    }, function(status){
                        alert('Error: ' + status);
                    });
                } else {
                    //alert('This apk does not support this function, Please update apk !');
                    window.location.href = url;
                }
            }
        }

        // 20220411 modify by Alan for#110231 : 調整預設解析度
        function createWindow (url) {
            // 20240321 modify by Alan for#159805 : electron升級後，兼容新舊版本
            const remote = window.nodeRequire('electron').remote || window.nodeRequire('@electron/remote');
            // 20230424 modify by 文蔚 for M#133324: 修改解析度支援1024*768
			const primaryDisplay = remote.screen.getPrimaryDisplay()
			const { width, height } = primaryDisplay.workAreaSize
			var widthLimit = width < 1140 ? true : false
			var heightLimit = height === 768 ? true : false
            var BrowserWindow = remote.BrowserWindow,
                windowOptions = {
                    width: config.setting.windowSize ? config.setting.windowSize[0] : 1140, // 20231205 modify by Alan for#152125 : 從config取得預設解析度
                    minWidth: widthLimit ? 1024 : 1140,
                    height: config.setting.windowSize ? config.setting.windowSize[1] : 660, // 20231205 modify by Alan for#152125 : 從config取得預設解析度
                    minHeight: heightLimit ? 728 : 660,
                    frame:false,
                    fullscreen: false,
                    fullscreenable: true,
                    titleBarStyle : 'customButtonsOnHover',
                    show: false,
                    webPreferences: {
                      nodeIntegration: true,
                      contextIsolation: false,
                    }
                };
            if(isPhone){
                windowOptions.minWidth = windowOptions.width = 411;
                windowOptions.minHeight = windowOptions.height = 731;
            }
            var newWin = new BrowserWindow(windowOptions);
            newWin.loadURL('file://'+__dirname+'/'+url);
            newWin.on('closed', function(){
                newWin = null;
            });
            newWin.once('ready-to-show', function(){
                if(isDebug)
                    newWin.webContents.openDevTools();
                newWin.show();
                if(isPhone){
                    newWin.setResizable(false);
                } else {
                    newWin.setFullScreen(config.setting.fullScreen == 'Y');
                }
                win.close();
            });
        }

        function createWindowNW (url) {
            var nw = nodeRequire('nw.gui'),
                settings = {
                    position: 'center',
                    min_width:1024,
                    min_height:600,
                    width:1024,
                    height:600,
                    resizable:true,
                    fullscreen:config.setting.fullScreen == 'Y',
                    frame: false,
                    show: false,
                    icon:'icon/icon.png'
                };
            nw.Window.open('www/'+url, settings, function(new_win) {
                if(isDebug)
                    new_win.showDevTools();
                new_win.on('loaded', function(){
                    new_win.show();
                    win.close();
                });
            });
        }
    }]);
}
